#include "network_client.h"

namespace engine
{
	bool NetworkClient::connect(const char* host, uint16 port)
	{
		if (!mLibEvent.isAlive())
		{
			if (!mLibEvent.start(host, port, 0))
				return false;
		}

		if (!mLibEvent.connect(host, port))
			return false;

		return true;
	}

	void NetworkClient::disconnect()
	{
		if (mHost)
		{
			mLibEvent.disconnect(mHost);
		}
	}

	void NetworkClient::addListener(NetworkClientListener* listener)
	{
		mListeners.push_back(listener);
	}

	void NetworkClient::removeListener(NetworkClientListener* listener)
	{
		mListeners.remove(listener);
	}

	NetworkStream& NetworkClient::beginStream()
	{
		mSendStream.clear();

		return mSendStream;
	}

	void NetworkClient::sendStream(const NetworkStream& stream)
	{
		if (mHost)
		{
			mLibEvent.send(stream.getData(), stream.getLength(), mHost);
		}
	}

	void NetworkClient::handleMessages()
	{
		Message* pmsg = NULL;

		while ((pmsg = mLibEvent.lockMessage()))
		{
			Message msg = *pmsg;

			mLibEvent.unlockMessage();

			switch (msg.type)
			{
			case Message::ConnectionSuccess:
				{
					mHost = msg.conn;

					ListenerList::iterator it = mListeners.begin();

					for (; it != mListeners.end(); ++it)
					{
						(*it)->onConnected();
					}
				}
				break;

			case Message::ConnectionFailed:
				{
					mHost = NULL;

					ListenerList::iterator it = mListeners.begin();

					for (; it != mListeners.end(); ++it)
					{
						(*it)->onConnectFailed();
					}
				}
				break;
			case Message::ConnectionBreak:
				{
					assert(mHost == msg.conn);

					mHost = NULL;

					ListenerList::iterator it = mListeners.begin();

					for (; it != mListeners.end(); ++it)
					{
						(*it)->onDisconnected();
					}

					mLibEvent.freeConnection(msg.conn);
				}
				break;

			case Message::ConnectionMessage:
				{
					mRecvStream.setData(msg.buff, msg.size);

					ListenerList::iterator it = mListeners.begin();

					for (; it != mListeners.end(); ++it)
					{
						mRecvStream.setPosition(0);

						(*it)->onMessage(mRecvStream);
					}

					mLibEvent.freeBuffer(msg.buff, msg.size);
				}
				break;

			default:
				assert(false);
			}
		}
	}

}
